package com.chenqq.camerademo.camera.helper;

import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;

import com.chenqq.camerademo.camera.bean.DeviceFilter;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

public class XmparserTools {

    public static DeviceFilter readEntryOne(final Context context, final XmlPullParser parser)
            throws XmlPullParserException, IOException {
        int vendorId = -1;
        int productId = -1;
        int deviceClass = -1;
        int deviceSubclass = -1;
        int deviceProtocol = -1;
        boolean exclude = false;
        String manufacturerName = null;
        String productName = null;
        String serialNumber = null;
        boolean hasValue = false;

        String tag;
        int eventType = parser.getEventType();
        while (eventType != XmlPullParser.END_DOCUMENT) {
            tag = parser.getName();
            if (!TextUtils.isEmpty(tag) && (tag.equalsIgnoreCase("usb-device"))) {
                if (eventType == XmlPullParser.START_TAG) {
                    hasValue = true;
                    vendorId = getAttributeInteger(context, parser, null, "vendor-id", -1);
                    if (vendorId == -1) {
                        vendorId = getAttributeInteger(context, parser, null, "vendorId", -1);
                        if (vendorId == -1)
                            vendorId = getAttributeInteger(context, parser, null, "venderId", -1);
                    }
                    productId = getAttributeInteger(context, parser, null, "product-id", -1);
                    if (productId == -1)
                        productId = getAttributeInteger(context, parser, null, "productId", -1);
                    deviceClass = getAttributeInteger(context, parser, null, "class", -1);
                    deviceSubclass = getAttributeInteger(context, parser, null, "subclass", -1);
                    deviceProtocol = getAttributeInteger(context, parser, null, "protocol", -1);
                    manufacturerName = getAttributeString(context, parser, null, "manufacturer-name", null);
                    if (TextUtils.isEmpty(manufacturerName))
                        manufacturerName = getAttributeString(context, parser, null, "manufacture", null);
                    productName = getAttributeString(context, parser, null, "product-name", null);
                    if (TextUtils.isEmpty(productName))
                        productName = getAttributeString(context, parser, null, "product", null);
                    serialNumber = getAttributeString(context, parser, null, "serial-number", null);
                    if (TextUtils.isEmpty(serialNumber))
                        serialNumber = getAttributeString(context, parser, null, "serial", null);
                    exclude = getAttributeBoolean(context, parser, null, "exclude", false);
                } else if (eventType == XmlPullParser.END_TAG) {
                    if (hasValue) {
                        return new DeviceFilter(vendorId, productId, deviceClass,
                                deviceSubclass, deviceProtocol, manufacturerName, productName,
                                serialNumber, exclude);
                    }
                }
            }
            eventType = parser.next();
        }
        return null;
    }

    /**
     * read as integer values with default value from xml(w/o exception throws)
     * resource integer id is also resolved into integer
     * @param parser
     * @param namespace
     * @param name
     * @param defaultValue
     * @return
     */
    private static final int getAttributeInteger(final Context context, final XmlPullParser parser,
                                                 final String namespace, final String name, final int defaultValue) {
        int result = defaultValue;
        try {
            String v = parser.getAttributeValue(namespace, name);
            if (!TextUtils.isEmpty(v) && v.startsWith("@")) {
                final String r = v.substring(1);
                final int resId = context.getResources().getIdentifier(r, null, context.getPackageName());
                if (resId > 0) {
                    result = context.getResources().getInteger(resId);
                }
            } else {
                int radix = 10;
                if (v != null && v.length() > 2 && v.charAt(0) == '0' &&
                        (v.charAt(1) == 'x' || v.charAt(1) == 'X')) {
                    // allow hex values starting with 0x or 0X
                    radix = 16;
                    v = v.substring(2);
                }
                result = Integer.parseInt(v, radix);
            }
        } catch (final Resources.NotFoundException e) {
            result = defaultValue;
        } catch (final NumberFormatException e) {
            result = defaultValue;
        } catch (final NullPointerException e) {
            result = defaultValue;
        }
        return result;
    }
    /**
     * read as boolean values with default value from xml(w/o exception throws)
     * resource boolean id is also resolved into boolean
     * if the value is zero, return false, if the value is non-zero integer, return true
     * @param context
     * @param parser
     * @param namespace
     * @param name
     * @param defaultValue
     * @return
     */
    private static final boolean getAttributeBoolean(final Context context, final XmlPullParser parser,
                                                     final String namespace, final String name,
                                                     final boolean defaultValue) {
        boolean result = defaultValue;
        try {
            String v = parser.getAttributeValue(namespace, name);
            if ("TRUE".equalsIgnoreCase(v)) {
                result = true;
            } else if ("FALSE".equalsIgnoreCase(v)) {
                result = false;
            } else if (!TextUtils.isEmpty(v) && v.startsWith("@")) {
                final String r = v.substring(1);
                final int resId = context.getResources().getIdentifier(r, null, context.getPackageName());
                if (resId > 0) {
                    result = context.getResources().getBoolean(resId);
                }
            } else {
                int radix = 10;
                if (v != null && v.length() > 2 && v.charAt(0) == '0' &&
                        (v.charAt(1) == 'x' || v.charAt(1) == 'X')) {
                    // allow hex values starting with 0x or 0X
                    radix = 16;
                    v = v.substring(2);
                }
                final int val = Integer.parseInt(v, radix);
                result = val != 0;
            }
        } catch (final Resources.NotFoundException e) {
            result = defaultValue;
        } catch (final NumberFormatException e) {
            result = defaultValue;
        } catch (final NullPointerException e) {
            result = defaultValue;
        }
        return result;
    }
    /**
     * read as String attribute with default value from xml(w/o exception throws)
     * resource string id is also resolved into string
     * @param parser
     * @param namespace
     * @param name
     * @param defaultValue
     * @return
     */
    private static final String getAttributeString(final Context context, final XmlPullParser parser, final String namespace, final String name, final String defaultValue) {
        String result = defaultValue;
        try {
            result = parser.getAttributeValue(namespace, name);
            if (result == null)
                result = defaultValue;
            if (!TextUtils.isEmpty(result) && result.startsWith("@")) {
                final String r = result.substring(1);
                final int resId = context.getResources().getIdentifier(r, null, context.getPackageName());
                if (resId > 0)
                    result = context.getResources().getString(resId);
            }
        } catch (final Resources.NotFoundException e) {
            result = defaultValue;
        } catch (final NumberFormatException e) {
            result = defaultValue;
        } catch (final NullPointerException e) {
            result = defaultValue;
        }
        return result;
    }

}
